package edu.whu.xterm.activity;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;
import org.jsoup.nodes.TextNode;
import org.jsoup.select.Elements;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.Browser;
import android.text.Html;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.text.style.URLSpan;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;
import edu.whu.xterm.Article;
import edu.whu.xterm.Head;
import edu.whu.xterm.R;
import edu.whu.xterm.activity.PostArticleActivity.PostType;
import edu.whu.xterm.http.RequestBuilder;
import edu.whu.xterm.util.Constants;
import edu.whu.xterm.util.StringUtils;
import edu.whu.xterm.widget.SpannableViewBinder;
import greendroid.widget.GActionBarItem;
import greendroid.widget.LoaderActionBarItem;

public class TopicAndReplyWforumActivity extends GDLoadingActivity implements
		AdapterView.OnItemClickListener {

	static final int POST_ARTICLE_REQUEST_CODE = 0x01;

	static final String TAG = "TopicAndReplyWforumActivity";

	public static final String KEY_URL = "url";

	static final int REFRESH_ITEM = 1;

	static final int DIALOG_ITEM_CLICK = 1;

	static final String BUNDLE_KEY_DATA = "bundle_key_data";

	static final String KEY_USER_ID = "key_user_id";

	private static final int[] TO = { R.id.topic_reply_author, R.id.topic_reply_time,
			R.id.topic_reply_serial, R.id.topic_reply_content, R.id.item_from, R.id.item_ip };

	private static final String[] FROM = { "AUTHOR", "TIME", "SERIAL", "CONTENT", "FROM", "IP" };

	View headView;

	View moreView;

	ListView replyView;

	BaseAdapter adapter;

	LoaderActionBarItem refreshItem;

	AsyncTask<String, Void, Result> task;

	Head mHead;

	List<Map<String, CharSequence>> mDataMap;

	List<Article> mData;

	int pageIndex;

	int totalPageCount;

	int floor;

	boolean headGenerated = false;

	String url;

	Intent userDetailIntent;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setActionBarContentView(R.layout.activity_topic_content);
		headView = getLayoutInflater().inflate(R.layout.topic_reply_detail_head, null);
		replyView = (ListView) findViewById(R.id.replies_list);

		replyView.addHeaderView(headView);
		replyView.setFastScrollEnabled(true);
		initLoadingView(replyView);

		// refreshItem = (LoaderActionBarItem)
		// getGActionBar().addItem(Type.Refresh, REFRESH_ITEM);

		url = getIntent().getStringExtra(KEY_URL);
		mData = new ArrayList<Article>();
		mDataMap = new ArrayList<Map<String, CharSequence>>();
		SimpleAdapter sAdapter = new SimpleAdapter(getGDApplication(), mDataMap,
				R.layout.topic_replay_listitem, FROM, TO);
		sAdapter.setViewBinder(new SpannableViewBinder());
		adapter = sAdapter;
		replyView.setAdapter(adapter);
		replyView.setOnItemClickListener(this);
		executeLoadTask();
	}

	@Override
	public void executeLoadTask() {
		pageIndex = 1;
		task = new TopicReplyAsyncTask((LoaderActionBarItem) getGActionBar().getItem(MainTabActivity.ITEM_REFRESH),
				TaskType.NEW);
		task.execute(url);
	}

	@Override
	protected void onStart() {
		super.onStart();
	}

	@Override
	protected void onStop() {
		super.onStop();
		if (task != null)
			task.cancel(true);
	}

	@Override
	public boolean onHandleActionBarItemClick(GActionBarItem item, int position) {
		switch (item.getItemId()) {
		case REFRESH_ITEM: {
			pageIndex = 1;
			refreshItem.setLoading(false);
			task = new TopicReplyAsyncTask(refreshItem, TaskType.NEW);
			task.execute(url);
			break;
		}
		default:
			break;
		}
		return super.onHandleActionBarItemClick(item, position);
	}

	@Override
	public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
		Bundle bd = new Bundle();
		if (position == 0) {
			bd.putParcelable(BUNDLE_KEY_DATA, mHead);
		} else {
			bd.putParcelable(BUNDLE_KEY_DATA, mData.get(position - 1));
		}
		showDialog(DIALOG_ITEM_CLICK, bd);
	}

	@Override
	protected void onPrepareDialog(int id, Dialog dialog, Bundle args) {
		super.onPrepareDialog(id, dialog, args);
		switch (id) {
		case DIALOG_ITEM_CLICK:
			break;

		default:
			break;
		}
		if (userDetailIntent == null)
			userDetailIntent = new Intent(getGDApplication(), UserDetailWforumActivity.class);
		userDetailIntent.putExtra(KEY_USER_ID,
				((Article) args.getParcelable(BUNDLE_KEY_DATA)).author);
	}

	void reset() {
		headGenerated = false;
		pageIndex = 1;
		mHead = null;
		mDataMap.clear();
	}

	@Override
	protected void onActivityResult(int arg0, int arg1, Intent arg2) {
		super.onActivityResult(arg0, arg1, arg2);
		switch (arg0) {
		case POST_ARTICLE_REQUEST_CODE:
			reset();
			executeLoadTask();
			break;

		default:
			break;
		}
	}

	@Override
	protected Dialog onCreateDialog(int id, final Bundle args) {
		switch (id) {
		case DIALOG_ITEM_CLICK: {
			return new AlertDialog.Builder(this).setItems(
					getGDApplication().isLogined() ? R.array.signed : R.array.unsigned,
					new DialogInterface.OnClickListener() {

						@Override
						public void onClick(DialogInterface dialog, int which) {
							switch (which) {
							case 0: {
								startActivity(userDetailIntent);
								break;
							}
							case 1: {
								if (getGDApplication().isLogined()) {
									Intent intent = new Intent(getGDApplication(),
											PostArticleActivity.class);
									intent.putExtra(BUNDLE_KEY_DATA,
											args.getParcelable(BUNDLE_KEY_DATA));
									intent.putExtra(PostType.POST_TYPE, PostType.REPLY_ARTICLE);
									startActivityForResult(intent, POST_ARTICLE_REQUEST_CODE);
								} else {
									onClick(dialog, 3);
								}
								break;
							}
							case 2: {
								Intent intent = new Intent(getGDApplication(),
										MailSendActivity.class);
								intent.putExtra(BUNDLE_KEY_DATA,
										args.getParcelable(BUNDLE_KEY_DATA));
								startActivity(intent);
								break;
							}

							case 3: {
								// TODO
								break;
							}
							default:
								break;
							}
						}
					}).create();
		}
		default:
			break;
		}
		return super.onCreateDialog(id, args);
	}

	enum Result {
		LOAD_SUCCESS, //
		LOAD_FAILED, //
		LOAD_MORE_FAILED, //
	}

	enum TaskType {
		MORE, //
		NEW, //
	}

	private class TopicReplyAsyncTask extends AsyncTask<String, Void, Result> {

		private LoaderActionBarItem loaderItem;

		private TaskType type;

		public TopicReplyAsyncTask(LoaderActionBarItem loaderItem, TaskType type) {
			this.loaderItem = loaderItem;
			this.type = type;
		}

		@Override
		protected void onPreExecute() {
			// loaderItem.setLoading(true);
		}

		@Override
		protected Result doInBackground(String... params) {

			List<Map<String, CharSequence>> tmpList = new ArrayList<Map<String, CharSequence>>();
			try {
				long start = System.currentTimeMillis();
				Document document = RequestBuilder.getBuilder().pageRequest(params[0]).call();
				Log.d(TAG, "page request time cost:" + (System.currentTimeMillis() - start));
				start = System.currentTimeMillis();
				Elements doc = document.select("table[width=98%] td[width=100%]");
				Elements reLinks = document.select("td[width=*] a[href^=postarticle");
				Log.d(TAG, "page process cost:" + (System.currentTimeMillis() - start));
				if (doc.isEmpty() || reLinks.isEmpty() || doc.size() != reLinks.size()) {
					return failed(type);
				}
				final int count = doc.size();
				for (int i = 0; i < count; i++) {
					Element ele = doc.get(i);
					String reId = reLinks.get(i).attr("href");
					int id = Integer.valueOf(reId.substring(reId.lastIndexOf("=") + 1));
					start = System.currentTimeMillis();
					List<Node> infoNodes = new ArrayList<Node>();
					for (;;) {
						Node node = ele.childNode(0);
						if (node instanceof TextNode) {
							if (StringUtils.isBlank(((TextNode) node).text())) {
								node.remove();
								break;
							}
							infoNodes.add(node);
						}
						node.remove();
					}
					List<Node> childNodes = ele.childNodes();
					final int size = childNodes.size();
					for (int j = size - 1; j > 0; j--) {
						Node node = childNodes.get(j);
						if (node instanceof TextNode
								&& "--".equals(((TextNode) node).text().trim())) {
							node.remove();
							break;
						}
						if (node instanceof Element
								&& !StringUtils.isBlank(((Element) node).text())) {
							infoNodes.add(node);
							if (node.toString().indexOf("修改") > 0) {
								break;
							}
						} else if (node instanceof TextNode
								&& !StringUtils.isBlank(((TextNode) node).text())
								&& !(node.toString().indexOf("此主题相关图片") > 0)) {
							infoNodes.add(node);
						}
						node.remove();
					}
					Article article = new Article();
					article.id = id;
					String authorBoard = infoNodes.get(0).toString();
					final int authorStart = authorBoard.indexOf(":") + 1;
					final int authorEnd = authorBoard.indexOf("(", authorStart);
					final int boardStart = authorBoard.indexOf(":", authorEnd) + 1;
					article.author = authorBoard.substring(authorStart, authorEnd).trim();
					article.board = authorBoard.substring(boardStart).trim();
					String titleStr = infoNodes.get(1).toString();
					article.title = titleStr.substring(titleStr.indexOf(":") + 1).trim();
					String timeStr = infoNodes.get(2).toString();
					final int timeStart = timeStr.indexOf("(") + 1;
					final int timeEnd = timeStr.indexOf(")", timeStart);
					article.time = timeStr.substring(timeStart, timeEnd).trim();
					String fromStr = ((Element) infoNodes.get(3)).toString();
					article.from = fromStr.indexOf("http") > 0 ? "web" : "term";
					final int ipStart = fromStr.indexOf("[FROM:") + 6;
					final int ipEnd = fromStr.indexOf("]", ipStart);
					article.ip = fromStr.substring(ipStart, ipEnd).trim();
					Elements links = ele.getElementsByTag("a");
					SpannableStringBuilder ssb = new SpannableStringBuilder();
					int index = 1;

					for (Element element : links) {
						String href = Constants.PATH_WFORUM + element.attr("href");
						SpannableString str = new SpannableString(getString(R.string.pic_name)
								+ index++);
						URLSpan span = new URLSpan(href) {

							@Override
							public void onClick(View widget) {
								// TODO
								Uri uri = Uri.parse(getURL());
								Context context = widget.getContext();
								Intent intent = new Intent(Intent.ACTION_VIEW, uri);
								intent.putExtra(Browser.EXTRA_APPLICATION_ID,
										context.getPackageName());
								startActivity(intent);
							}
						};
						ssb.append("\n");
						ssb.append(str);
						ssb.setSpan(span, ssb.length() - 3, ssb.length(),
								Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
						element.remove();
					}
					String tmp = Html.fromHtml(ele.html()).toString().trim();
					if (!links.isEmpty())
						ssb.insert(0, tmp);
					int length = tmp.length();
					if (length > 1600) {
						int endIndex = tmp.lastIndexOf("】");
						if (endIndex > 0) {
							tmp = tmp.substring(0, endIndex + 60 > length ? length
									: (endIndex + 60))
									+ "\n...\n(后面省略)";
						}
					}
					article.content = links.isEmpty() ? tmp : ssb;
					if (!headGenerated) {
						mHead = new Head(article);
						headGenerated = true;
						Elements more = document.select("tr > td[nowrap=nowarp]");
						Element articleCount = (Element) more.first().childNodes().get(1);
						totalPageCount = (int) Math.ceil((double) Integer.valueOf(articleCount
								.text()) / 15);
					} else {
						mData.add(article);
						Map<String, CharSequence> data = new HashMap<String, CharSequence>();
						data.put(FROM[0], article.author);
						data.put(FROM[1], article.time);
						data.put(FROM[2], "#" + (++floor));
						data.put(FROM[3], article.content);
						data.put(FROM[4], article.from);
						data.put(FROM[5], article.ip);
						if (type == TaskType.MORE) {
							mDataMap.add(data);
						} else {
							tmpList.add(data);
						}
					}
					Log.d(TAG, "generate article cost:" + (System.currentTimeMillis() - start));
				}

			} catch (Exception e) {
				e.printStackTrace();
				return failed(type);
			}
			if (type == TaskType.NEW) {
				mDataMap.clear();
				mDataMap.addAll(tmpList);
			}
			return Result.LOAD_SUCCESS;

		}

		private Result failed(TaskType type) {
			if (type == TaskType.MORE) {
				return Result.LOAD_MORE_FAILED;
			} else {
				return Result.LOAD_FAILED;
			}
		}

		@Override
		protected void onPostExecute(Result result) {
			switch (result) {
			case LOAD_SUCCESS: {
				getGActionBar().setTitle(mHead.title);
				((TextView) headView.findViewById(R.id.topic_content_author)).setText(mHead.author);
				((TextView) headView.findViewById(R.id.topic_content_time)).setText(mHead.time);
				TextView content = ((TextView) headView.findViewById(R.id.topic_content_text));
				content.setText(mHead.content);
				if (mHead.content instanceof Spannable) {
					content.setMovementMethod(LinkMovementMethod.getInstance());
					content.setFocusable(false);
					content.setFocusableInTouchMode(false);
				}
				((TextView) headView.findViewById(R.id.item_from)).setText(mHead.from);
				((TextView) headView.findViewById(R.id.item_ip)).setText(mHead.ip);
				loadSuccessed();
				adapter.notifyDataSetChanged();

				if (pageIndex == totalPageCount && moreView != null) {
					replyView.removeFooterView(moreView);
				} else {
					if (moreView == null) {
						moreView = getLayoutInflater().inflate(R.layout.replies_more, null);
					}
					moreView.findViewById(R.id.loading_widget).setVisibility(View.GONE);
					if (totalPageCount > 1 && replyView.getFooterViewsCount() == 0) {
						moreView.setOnClickListener(new View.OnClickListener() {

							@Override
							public void onClick(View v) {
								moreView.findViewById(R.id.loading_widget).setVisibility(
										View.VISIBLE);
								task = new TopicReplyAsyncTask(loaderItem, TaskType.MORE);
								task.execute(new MoreUrl(url).setPage(++pageIndex).toString());
							}
						});
						replyView.addFooterView(moreView);
					}
				}
				break;
			}
			case LOAD_FAILED: {
				loadFailed();
				break;
			}
			case LOAD_MORE_FAILED: {
				moreView.findViewById(R.id.loading_widget).setVisibility(View.GONE);
				Toast.makeText(getApplicationContext(), R.string.load_failed, Toast.LENGTH_SHORT)
						.show();
			}
			default:
				break;
			}
			// loaderItem.setLoading(false);
			task = null;
		}
	}

	public static class MoreUrl {

		public static final String DELIM = "&";
		public String pre;
		public String pos;
		public String page;

		public MoreUrl(String pre) {
			this.pre = pre;
			pos = "pos=-1";
		}

		public MoreUrl setPage(int page) {
			this.page = "page=" + page;
			return this;
		}

		@Override
		public String toString() {
			return pre + "&" + pos + "&" + page;
		}
	}
}